package com.lightsh.cleancode;

/**
 * A simple test for learning 《Clean Code》
 * @author lightsh
 *
 */
public class ComparisonCompactor {
	private final int mLevel;
	private final String mOriginalStr;
	private final String mTargetStr;
	
	private int mFirstMarkIndex;
	private int mLastMarkIndex;
	
	public ComparisonCompactor(int level, String original, String target){
		mLevel = level;
		mOriginalStr = original;
		mTargetStr = target;
	}
	
	private String doCompare(){
		final String TO_FLAG = " -> ";
		if(mOriginalStr != null && mTargetStr != null){
			final int originalSize = mOriginalStr.length();
			final int targetSize = mTargetStr.length();
			int firstNotEqualPoint = findFirstNotEqualPoint();
			if(firstNotEqualPoint == originalSize){
				if(originalSize == targetSize){
					// equal
					return mOriginalStr + TO_FLAG + mTargetStr;
				}else{
					// original equal target's prefix
					return mOriginalStr + "[]" + TO_FLAG + mTargetStr.substring(0, firstNotEqualPoint) + "[" + mTargetStr.substring(firstNotEqualPoint) + "]";
				}
			}else if(firstNotEqualPoint == targetSize){
				// target equal original's prefix
				return mOriginalStr.substring(0, firstNotEqualPoint) + "[" + mOriginalStr.substring(firstNotEqualPoint)  + "]" + TO_FLAG + mTargetStr + "[]";
			}else{
				int lastEqualPoint = findLastEqualPoint(firstNotEqualPoint);
				if(lastEqualPoint == originalSize){
					// firstNotEqualPoint to end is not equal
					return mOriginalStr.substring(0, firstNotEqualPoint) + "[" + mOriginalStr.substring(firstNotEqualPoint)  + "]" + TO_FLAG + mTargetStr.substring(0, firstNotEqualPoint) + "[" + mTargetStr.substring(firstNotEqualPoint) + "]";
				}else{
					// firstNotEqualPoint to lastEqualPoint is not equal, lastEqualPoint to end is equal
					int targetTailIndex = targetSize - (originalSize - lastEqualPoint);
					String targetMiddle = mTargetStr.substring(firstNotEqualPoint, targetTailIndex);
					String targetTail = mTargetStr.substring(targetTailIndex);
					return mOriginalStr.substring(0, firstNotEqualPoint) + "[" + mOriginalStr.substring(firstNotEqualPoint, lastEqualPoint)  + "]" + mOriginalStr.substring(lastEqualPoint) + TO_FLAG + mTargetStr.substring(0, firstNotEqualPoint) + "[" + targetMiddle + "]" + targetTail;
				}				
			}
		}else{
			return (mOriginalStr == null ? "null" : mOriginalStr) + TO_FLAG + (mTargetStr == null ? "null" : mTargetStr);
		}
	}
	
	private int findFirstNotEqualPoint(){
		final int originalSize = mOriginalStr.length();
		final int targetSize = mTargetStr.length();
		for(int i = 0; i < originalSize; ++i){
			if(i >= targetSize || mOriginalStr.charAt(i) != mTargetStr.charAt(i)){
				return i;
			}
		}
		return originalSize;
	}
	
	private int findLastEqualPoint(int startIndex){
		final int originalSize = mOriginalStr.length();
		final int targetSize = mTargetStr.length();
		for(int i = startIndex; i < originalSize; ++i){
			for(int j = startIndex; j < targetSize; j++){
				if(isTailEqual(i, j)){
					return i;
				}
			}
		}
		return originalSize;
	}
	private boolean isTailEqual(int oIndex, int tIndex){
		return mOriginalStr.substring(oIndex).equals(mTargetStr.substring(tIndex));
	}
	
	public String compact(String startMsg){
		StringBuilder builder = new StringBuilder();
		if(startMsg != null && startMsg.length() > 0){
			builder.append(startMsg).append(' ');
		}		
		builder.append(doCompare());
		return builder.toString();
	}
}
